<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>bash 的环境变量和 shell 变量 - whowin - 发表我个人原创作品的技术博客</title>
  <meta name="renderer" content="webkit" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>

<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />

<meta name="theme-color" content="#f8f5ec" />
<meta name="msapplication-navbutton-color" content="#f8f5ec">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="#f8f5ec">


<meta name="author" content="whowin" /><meta name="description" content="shell变量和环境变量相关的一些概念" /><meta name="keywords" content="linux, socket, hugo, dos" />






<meta name="generator" content="Hugo 0.97.3 with theme even" />


<link rel="canonical" href="https://whowin.gitee.io/post/blog/linux/0001-environment-variables-and-shell-variables/" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">



<link href="/sass/main.min.e3fea119b1980e848b03dffbeddb11dd0fba483eed0e5f11870fb8e31f145bbd.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.1.20/dist/jquery.fancybox.min.css" integrity="sha256-7TyXnr2YU040zfSP+rEcz29ggW4j56/ujTPwjMzyqFY=" crossorigin="anonymous">


<meta property="og:title" content="bash 的环境变量和 shell 变量" />
<meta property="og:description" content="shell变量和环境变量相关的一些概念" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://whowin.gitee.io/post/blog/linux/0001-environment-variables-and-shell-variables/" /><meta property="article:section" content="post" />
<meta property="article:published_time" content="2022-04-10T16:43:29+08:00" />
<meta property="article:modified_time" content="2022-04-10T16:43:29+08:00" />

<meta itemprop="name" content="bash 的环境变量和 shell 变量">
<meta itemprop="description" content="shell变量和环境变量相关的一些概念"><meta itemprop="datePublished" content="2022-04-10T16:43:29+08:00" />
<meta itemprop="dateModified" content="2022-04-10T16:43:29+08:00" />
<meta itemprop="wordCount" content="5519">
<meta itemprop="keywords" content="shell,bash,source,printenv,环境变量,declare,export," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="bash 的环境变量和 shell 变量"/>
<meta name="twitter:description" content="shell变量和环境变量相关的一些概念"/>

<!--[if lte IE 9]>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
<![endif]-->

<!--[if lt IE 9]>
  <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->

  <script async src="/js/busuanzi.pure.mini.js"></script><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9724909319263152"
     crossorigin="anonymous"></script>


</head>
<body>
  <div id="mobile-navbar" class="mobile-navbar">
  <div class="mobile-header-logo">
    <a href="/" class="logo">WhoWin</a>
  </div>
  <div class="mobile-navbar-icon">
    <span></span>
    <span></span>
    <span></span>
  </div>
</div>
<nav id="mobile-menu" class="mobile-menu slideout-menu">
  <ul class="mobile-menu-list">
    <a href="/">
        <li class="mobile-menu-item">首页</li>
      </a><a href="/post/">
        <li class="mobile-menu-item">文章归档</li>
      </a><a href="/article-categories/categories/">
        <li class="mobile-menu-item">文章分类</li>
      </a><a href="/tags/">
        <li class="mobile-menu-item">文章标签</li>
      </a><a href="/about/about/">
        <li class="mobile-menu-item">关于</li>
      </a>
  </ul>

  


</nav>

  <div class="container" id="mobile-panel">
    <header id="header" class="header">
        <div class="logo-wrapper">
  <a href="/" class="logo">WhoWin</a>
  
  <div style="position:absolute; left: 80px; top: 75px; color: crimson">
      ———开源和分享是技术发展的源泉和动力；本博客所有文章均为原创
  </div>
</div>





<nav class="site-navbar">
  <ul id="menu" class="menu">
    <li class="menu-item">
        <a class="menu-item-link" href="/">首页</a>
      </li><li class="menu-item">
        <a class="menu-item-link" href="/post/">文章归档</a>
      </li><li class="menu-item">
        <a class="menu-item-link" href="/article-categories/categories/">文章分类</a>
      </li><li class="menu-item">
        <a class="menu-item-link" href="/tags/">文章标签</a>
      </li><li class="menu-item">
        <a class="menu-item-link" href="/about/about/">关于</a>
      </li>
  </ul>
</nav>

    </header>

    <main id="main" class="main">
      <div class="content-wrapper">
        <div id="content" class="content">
          <article class="post">
    
    <header class="post-header">
      <h1 class="post-title">bash 的环境变量和 shell 变量</h1>

      <div class="post-meta">
        <span class="post-time"> 2022-04-10 </span>
        <div class="post-category">
            <a href="/categories/linux/"> Linux </a>
            </div>
        
      </div>
    </header>

    <div class="post-toc" id="post-toc">
  <h2 class="post-toc-title">文章目录</h2>
  <div class="post-toc-content">
    <nav id="TableOfContents">
  <ul>
    <li>
      <ul>
        <li><a href="#1-导言">1. 导言</a></li>
        <li><a href="#2-终端是如何启动-shell-的">2. 终端是如何启动 shell 的</a></li>
        <li><a href="#3-shell-变量和环境变量">3. shell 变量和环境变量</a></li>
        <li><a href="#4-bash-如何将环境变量传给子进程">4. bash 如何将环境变量传给子进程</a></li>
        <li><a href="#5-在当前环境下运行程序">5. 在当前环境下运行程序</a></li>
        <li><a href="#6-结语">6. 结语</a></li>
      </ul>
    </li>
  </ul>
</nav>
  </div>
</div>
    <div class="post-content">
      <p>本文简单介绍了 bash 的启动过程；shell 变量和环境变量的区别及相互转换；环境变量传递给子进程的过程；在当前环境下执行脚本及其实际应用，本文适合 Linux 初学者。</p>
<h2 id="1-导言">1. 导言</h2>
<ul>
<li>
<p><code>shell</code> 是一个 <code>Linux</code> 的命令行解释器，<code>Linux</code> 下有很多 <code>shell</code>，其中 <code>ubuntu</code> 中默认的 <code>shell</code> 应该是 <strong>dash</strong>，因为我们看到 <code>/bin/sh</code> 被链接到了 <strong>dash</strong></p>
<p><img src="https://whowin.gitee.io/images/100001/sh_point_to_dash.png" alt="/bin/sh&amp;ndash;&gt;dash"></p>
<center><b>图1：/bin/sh指向dash</b></center>
</li>
</ul>
<hr>
<ul>
<li>但是当你启动终端时(不管是在桌面还是远程)，默认启动的却是 <strong>bash</strong>(Bourne-Again SHell)，<code>bash</code> 是 <code>GNU(Gnu's Not Unix)</code> 开发的；</li>
<li>使用 <code>cat /etc/shells</code> 命令可以看到在你的 <code>Linux</code> 下有那些 <code>shell</code>；使用 <code>echo $SHELL</code> 可以看到当前你正在使用的 <code>shell</code>；</li>
<li>本文中如无特别说明，<code>shell</code> 指的是 <code>bash</code>，所有范例在 <code>ubuntu 20.04</code> 下完成，在更高版本的 <code>ubuntu</code> 上，可能会有些微区别；在较低版本的 <code>ubuntu</code> 上不能保证有相同的效果。</li>
</ul>
<h2 id="2-终端是如何启动-shell-的">2. 终端是如何启动 shell 的</h2>
<ul>
<li>
<p><code>ubuntu</code> 的 1 号进程是 <code>systemd</code>，这是 <code>ubuntu</code> 在加载完 <code>Linux</code> 内核后启动的第一个进程，是所有其它进程的祖宗；</p>
</li>
<li>
<p>你可能用 <code>ps aux(ps -ef)</code> 命令发现 1 号进程是 <strong>/sbin/init</strong>，而不是 <strong>systemd</strong>，但你用 <code>ls -l /sbin/init</code> 看一下就会恍然大悟；</p>
<p><img src="https://whowin.gitee.io/images/100001/first_process.png" alt="1号进程"></p>
<center><b>图2：1号进程</b></center>
<p><img src="https://whowin.gitee.io/images/100001/init_point_to_systemd.png" alt="init进程指向systemd"></p>
<center><b>图3：/sbin/init指向systemd</b></center>
</li>
</ul>
<hr>
<ul>
<li>
<p>当你在 <code>ubuntu</code> 桌面版上启动一个终端时，会启动一个 <strong>gnome-terminal</strong> 进程，<code>gnome-terminal</code> 进程启动了 <strong>bash</strong> 进程，这样你就看到可爱的提示符了，这个过程使用 <code>pstree</code> 命令一目了然；</p>
<p><img src="https://whowin.gitee.io/images/100001/terminal-bash.png" alt="gnome-terminal进程启动bash"></p>
<center><b>图4：gnome-terminal进程启动bash</b></center>
</li>
</ul>
<hr>
<ul>
<li>
<p>当你使用 <code>ssh</code> 客户端远程登录到 <code>Linux</code> 系统时，<strong>bash</strong> 进程是由 <strong>sshd</strong> 进程启动的，这个也可以用 <code>pstree</code> 命令看到</p>
<p><img src="https://whowin.gitee.io/images/100001/sshd-bash.png" alt="sshd进程启动bash"></p>
<center><b>图5：sshd进程启动bash</b></center>
</li>
</ul>
<hr>
<ul>
<li>只有启动了 <code>bash</code> 你才拥有了一个 <code>shell</code> 环境，你才能够在终端上输入命令，你从键盘输入的任何内容都必须由 <code>bash</code> 进行解释并做出进一步的处理。</li>
</ul>
<h2 id="3-shell-变量和环境变量">3. shell 变量和环境变量</h2>
<ul>
<li>
<p><strong>shell 变量</strong></p>
<ul>
<li><code>shell</code> 管理着一个变量表，这使得用户可以自己定义变量，这些变量是在 <code>shell</code> 下建立，由 <code>shell</code> 管理，在 <code>shell</code> 下使用</li>
<li>在启动 <code>shell(bash)</code> 的时候，<code>shell</code> 会创建一些变量(不同的 <code>shell</code> 创建的变量会有所不同)，同时，<code>shell</code> 在启动过程中还会去执行一些可以由客户自定义的脚本，比如：在启动 <code>bash</code> 时会执行：<strong>/etc/bash.bashrc</strong>，在登录时会执行：<strong>~/.bashrc</strong>等，这些脚本通常也会建立一些变量；</li>
<li>由于有些脚本是在用户登录时执行的，比如：<strong>~/.bashrc</strong>，而这个脚本是放在用户的 <strong>home</strong> 目录下的，这就使得不同的用户在登录时可以执行不同的脚本，从而每个用户在登录后所建立的 <code>shell</code> 变量也可以是不一样的</li>
<li>在 <code>shell</code> 下，可以直接用：<code>变量名=变量值</code> 的方法定义或修改 <code>shell</code> 变量；也可以用：<code>unset 变量名</code> 来删除变量，按照惯例，<code>shell</code> 变量名使用 <strong>大写字母</strong></li>
<li>使用 <code>set</code> 命令可以查看当前所有的 <code>shell</code> 变量；用 <code>echo $变量名</code> 可以显示指定变量名的值。</li>
</ul>
</li>
<li>
<p><strong>环境变量</strong></p>
<ul>
<li>环境变量也是 <code>shell</code> 变量，但环境变量却不等同于 <code>shell</code> 变量，我们暂时把不是环境变量的 <code>shell</code> 变量称作 <strong>普通 shell 变量</strong>，在 <code>bash</code> 内部，环境变量与普通 <code>shell</code> 变量的区别，仅仅是一个不同的标记而已；</li>
<li>环境变量和普通 <code>shell</code> 变量的最主要的区别是，在建立一个子进程时，环境变量会被传递给这个子进程，而普通 <code>shell</code> 变量不会，所以，环境变量可能会对一个子进程的行为产生影响，因为子进程可以根据环境变量的值做出不同的动作；</li>
<li>环境变量可以使用 <code>export 变量名=变量值</code> 进行设置，可以像普通 <code>shell</code> 变量一样用 <code>unset 变量名</code> 进行删除；</li>
<li>可以使用 <code>printenv</code> 命令查看所有的环境变量；用 <code>echo $变量名</code> 可以显示指定环境变量的值；也可以用 <code>printenv 环境变量名</code> 来显示一个环境变量的值；</li>
<li><code>env</code> 如果不带参数的话，也是可以显示环境变量的，但这个命令主要用于在指定环境下执行命令。</li>
</ul>
</li>
<li>
<p><strong>关于 <em>env</em> 命令的两个例子</strong></p>
<ul>
<li><code>env 环境变量名=变量值 命令</code> 和 <code>env -u 环境变量名 命令</code> 都只能临时在一个新的环境中改变或者删除一个变量，用于在一个指定的环境中执行命令，这一点在很多文章中都没有明确说明；</li>
<li>下面的例子设置了一个临时环境变量 <strong>ENV_VAR_1</strong>，并且在这个临时环境中将这个变量的值打印出来：
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ printenv ENV_VAR_1                           <span class="c1"># 当前环境下，不存在环境变量 ENV_VAR_1</span>
</span></span><span class="line"><span class="cl">$ env <span class="nv">ENV_VAR_1</span><span class="o">=</span>first_value printenv ENV_VAR_1 <span class="c1"># 临时设置环境变量并打印出值</span>
</span></span><span class="line"><span class="cl">first_value                                    <span class="c1"># 临时设置的环境变量ENV_VAR_1的值</span>
</span></span><span class="line"><span class="cl">$ printenv ENV_VAR_1                           <span class="c1"># 当前环境下，仍然不存在环境变量 ENV_VAR_1</span>
</span></span><span class="line"><span class="cl">$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>下面的例子中在临时环境中删除一个在当前环境中存在的环境变量，在临时环境中打印该环境变量为空，确定该环境变量在临时环境中已经不存在；
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">ENV_VAR_2</span><span class="o">=</span>second_value                  <span class="c1"># 当前环境下设置环境变量</span>
</span></span><span class="line"><span class="cl">$ printenv ENV_VAR_2                             <span class="c1"># 打印该环境变量的值</span>
</span></span><span class="line"><span class="cl">second_value
</span></span><span class="line"><span class="cl">$ env -u ENV_VAR_2 printenv SHELL ENV_VAR_2 USER <span class="c1"># 临时删除该环境变量，并在临时环境中打印该变量</span>
</span></span><span class="line"><span class="cl">/bin/bash                                        <span class="c1"># SHELL变量的值</span>
</span></span><span class="line"><span class="cl">demouser                                         <span class="c1"># USER变量的值，偏偏没有变量ENV_VAR_2的值</span>
</span></span><span class="line"><span class="cl">$ printenv ENV_VAR_2                             <span class="c1"># 当前环境下打印环境变量ENV_VAR_2</span>
</span></span><span class="line"><span class="cl">second_value
</span></span><span class="line"><span class="cl">$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
</li>
<li>
<p><strong>环境变量和普通 shell 变量的转换</strong></p>
<ul>
<li>普通 <code>shell</code> 变量，通过 <code>export 变量名</code> 可以转变成环境变量；
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ set<span class="p">|</span>grep VAR_TO_ENVVAR                <span class="c1"># 没有VAR_TO_ENVVAR这个shell变量</span>
</span></span><span class="line"><span class="cl">$ <span class="nv">VAR_TO_ENVVAR</span><span class="o">=</span>convert_var_to_envvar   <span class="c1"># 设置VAR_TO_ENVVAR</span>
</span></span><span class="line"><span class="cl">$ set<span class="p">|</span>grep VAR_TO_ENVVAR                <span class="c1"># VAR_TO_ENVVAR是一个shell变量</span>
</span></span><span class="line"><span class="cl"><span class="nv">VAR_TO_ENVVAR</span><span class="o">=</span>convert_var_to_envvar
</span></span><span class="line"><span class="cl">$ printenv<span class="p">|</span>grep VAR_TO_ENVVAR           <span class="c1"># VAR_TO_ENVVAR不是一个环境变量</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">export</span> VAR_TO_ENVVAR                  <span class="c1"># 执行export命令</span>
</span></span><span class="line"><span class="cl">$ printenv<span class="p">|</span>grep VAR_TO_ENVVAR           <span class="c1"># VAR_TO_ENVVAR已经变成一个环境变量</span>
</span></span><span class="line"><span class="cl"><span class="nv">VAR_TO_ENVVAR</span><span class="o">=</span>convert_var_to_envvar
</span></span><span class="line"><span class="cl">$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>普通 <code>shell</code> 变量，通过 <code>declare -x 变量名</code> 可以转变成环境变量：
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">unset</span> VAR_TO_ENVVAR                   <span class="c1"># 删除变量VAR_TO_ENVVAR</span>
</span></span><span class="line"><span class="cl">$ <span class="nv">VAR_TO_ENVVAR</span><span class="o">=</span>convert_var_to_envvar   <span class="c1"># 设置VAR_TO_ENVVAR</span>
</span></span><span class="line"><span class="cl">$ set<span class="p">|</span>grep VAR_TO_ENVVAR                <span class="c1"># VAR_TO_ENVVAR是一个shell变量</span>
</span></span><span class="line"><span class="cl"><span class="nv">VAR_TO_ENVVAR</span><span class="o">=</span>convert_var_to_envvar
</span></span><span class="line"><span class="cl">$ printenv<span class="p">|</span>grep VAR_TO_ENVVAR           <span class="c1"># VAR_TO_ENVVAR不是一个环境变量</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">declare</span> -x VAR_TO_ENVVAR              <span class="c1"># 执行declare命令</span>
</span></span><span class="line"><span class="cl">$ printenv<span class="p">|</span>grep VAR_TO_ENVVAR           <span class="c1"># VAR_TO_ENVVAR已经变成一个环境变量</span>
</span></span><span class="line"><span class="cl"><span class="nv">VAR_TO_ENVVAR</span><span class="o">=</span>convert_var_to_envvar
</span></span><span class="line"><span class="cl">$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>环境变量，通过 <code>declare +x 变量名</code> 可以转变成普通shell变量：
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">ENV_VAR_1</span><span class="o">=</span>testing    <span class="c1"># 设置一个环境变量</span>
</span></span><span class="line"><span class="cl">$ printenv<span class="p">|</span>grep ENV_VAR_1     <span class="c1"># 确认设置成功</span>
</span></span><span class="line"><span class="cl"><span class="nv">ENV_VAR_1</span><span class="o">=</span>testing
</span></span><span class="line"><span class="cl">$ <span class="nb">declare</span> +x ENV_VAR_1        <span class="c1"># 执行declare +x命令</span>
</span></span><span class="line"><span class="cl">$ printenv<span class="p">|</span>grep ENV_VAR_1     <span class="c1"># 该变量已经不再是环境变量</span>
</span></span><span class="line"><span class="cl">$ set<span class="p">|</span>grep ENV_VAR_1          <span class="c1"># 该变量仍然是一个普通shell变量</span>
</span></span><span class="line"><span class="cl"><span class="nv">ENV_VAR_1</span><span class="o">=</span>testing
</span></span><span class="line"><span class="cl">$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li><code>declare 变量名=变量值</code> 可以用来设置或修改一个普通 <code>shell</code> 变量的值；<code>declare -x 变量名=变量值</code> 可以用来设置或修改一个环境变量的值；<code>declare -x 变量名</code> 可以将普通 <code>shell</code> 变量变成环境变量；<code>declare +x 变量名</code> 可以将环境变量变成普通shell变量；</li>
</ul>
</li>
</ul>
<blockquote>
<p>在 <code>Bourne Shell</code> 家族中(<code>bash - Bourne-Again SHell</code>)对变量和环境变量的区分确实不是很严格，很容易混为一谈，比如：两者按惯例都是用大写字母表示，设置和删除方法相同；但是在 <code>C Shell(csh)</code> 是进行了严格区分的，在 <code>csh</code> 中，按惯例 <code>shell</code> 变量使用小写字母，环境变量使用大写字母，<code>shell</code> 变量使用 <code>set</code> 和 <code>unset</code> 命令进行设置和删除，而环境变量必须用 <code>setenv</code> 和 <code>unsetenv</code> 命令进行设置和删除。</p>
</blockquote>
<h2 id="4-bash-如何将环境变量传给子进程">4. bash 如何将环境变量传给子进程</h2>
<ul>
<li>
<p><strong>bash 如何执行一个命令</strong></p>
<ul>
<li><code>shell</code> 在收到一个换行符(<code>new line</code>，<code>ASCII</code> 码 <code>0x0A</code>)时开始解释命令行的命令；</li>
<li><code>shell</code> 查找命令是否有别名(<code>alias</code>)，如果有则用别名代替命令；</li>
<li>如果命令中不包含 <code>&quot;/&quot;</code>，<code>shell</code> 首先查找同名函数，如果有，执行这个函数即可；</li>
<li>如果没有同名函数则查找内建命令，如果是内建命令，则在 <code>bash</code> 内部执行即可；</li>
<li>如果也不是内建命令，则根据环境变量 <strong>PATH</strong> 的顺序查找命令文件；</li>
<li>如果找不到命令文件，则显示错误信息并回到提示符接收下面的命令；</li>
<li>如果找到命令文件或者命令中有 <code>&quot;/&quot;</code> 字符，<code>bash</code> 会 <code>fork</code> 一个子进程，自身进程执行 <strong>wait()</strong> 等待子进程结束，然后在子进程中执行 <strong>execve()</strong>，一切的其他工作交给 <strong>execve()</strong> 来处理；</li>
</ul>
</li>
<li>
<p><strong>环境变量的传递</strong></p>
<ul>
<li>
<p>我们看一下 <strong>execve()</strong> 的手册</p>
<p><img src="https://whowin.gitee.io/images/100001/man-execve.png" alt="execve()说明"></p>
<center><b>图6：execve()手册</b></center>
</li>
</ul>
<hr>
<ul>
<li>在执行 <strong>execve()</strong> 时，需要传递三个参数过去，<code>filename</code> - 要执行的程序文件名；<code>argv[]</code> - 执行这个程序需要的参数；<code>envp</code> - 环境变量；<strong>环境变量就是这样传递给了可执行程序</strong>；</li>
<li>大家可能注意到，<code>shell</code> 不仅可以执行一个二进制的程序，也可以执行一个 <code>shell</code> 脚本(<code>ASCII</code> 文本文件)，我们并不需要告诉 <code>shell</code> 我们在执行那种文件，而 <code>shell</code> 却不会搞错，其实这个识别过程也是 <strong>execve()</strong> 的功劳；
<blockquote>
<p><strong>execve()</strong> 在执行程序时首先要读出文件的前 <code>128</code> 个字节，用以分析文件的类别，以便用适当的方式执行这个文件；比如：<code>shell</code> 脚本文件的前两个字符是 <code>&quot;#!&quot;</code>，这一点在手册中有明确说明；<code>ELF</code> 文件的前四个字符是：<code>0x45 0x4c 0x46 0x7c</code> 等，还有其它不同的可执行格式，这个过程其实还是比较复杂的，但是和 <code>shell</code> 变量毫无关系，所以不在本文讨论的范围内；</p>
</blockquote>
</li>
</ul>
</li>
<li>
<p><strong>一个打印环境变量的C程序</strong></p>
<ul>
<li>该程序只是验证传递给子进程的环境变量不包括普通 <code>shell</code> 变量</li>
<li>源代码，文件名：<code>print_env.c</code>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-C" data-lang="C"><span class="line"><span class="cl"><span class="cp">#include</span><span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">extern</span> <span class="kt">char</span> <span class="o">**</span><span class="n">environ</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">environ</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">printf</span><span class="p">(</span><span class="s">&#34;*%s</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">environ</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>编译执行
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ gcc print_env.c -o print_env
</span></span><span class="line"><span class="cl">$ ./print_env
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>本程序打印出的环境变量与 <code>printenv</code> 命令打印出的结果一致。</li>
</ul>
</li>
<li>
<p><strong>跟踪程序的执行</strong></p>
<ul>
<li>
<p>用 <code>strace ./print_env</code> 可以清楚地看到环境变量被传递给了程序 <code>print_env</code></p>
<p><img src="https://whowin.gitee.io/images/100001/strace_print_env.png" alt="跟踪程序print_env"></p>
<center><b>图7：跟踪程序print_env</b></center>
</li>
</ul>
<hr>
<ul>
<li>我们先用 <code>printenv|wc -l</code> 打印出环境变量的数量，然后我们看到有相同数量的变量被传递给了我们的程序 <code>print_env</code>；</li>
</ul>
</li>
<li>
<p><strong>环境变量对启动程序的影响</strong></p>
<ul>
<li>
<p>上面这个小程序我们在运行时是使用 <code>./print_env</code> 的方式运行的，其中 <code>&quot;./&quot;</code> 表示当前路径，但是这个程序其实就在当前目录下，我们为什么一定要指定路径呢？我们试一下不指定路径会怎样</p>
<p><img src="https://whowin.gitee.io/images/100001/command_not_found.png" alt="command not found"></p>
<center><b>图8：命令执行失败</b></center>
</li>
</ul>
<hr>
<ul>
<li>
<p>这是因为 <code>shell</code> 是沿着环境变量 <strong>PATH</strong> 的顺序来查找命令文件的，而当前目录 <code>./</code> 并不在当前的 <strong>PATH</strong> 中，我们可以试着把 <code>./</code> 加入到环境变量 <strong>PATH</strong> 中，然后再运行一下试试；</p>
<p><img src="https://whowin.gitee.io/images/100001/print_env_successfully.png" alt="执行print_env成功"></p>
<center><b>图9：执行print_env成功</b></center>
</li>
</ul>
<hr>
<ul>
<li>正如我们所期待的，执行成功了</li>
</ul>
</li>
<li>
<p><strong>子进程中无法修改父进程环境的环境变量</strong></p>
<ul>
<li><code>shell</code> 传递给的程序的环境仅仅是父进程环境的一个副本，所以我们在程序中改变这个副本中的变量都无法改变父进程的环境，当程序运行结束时，这个环境副本将被销毁；</li>
<li>下面这个例子我们首先在 <code>shell</code> 下定义一个环境变量 <code>ENV_VAR_1</code>，然后编写一个脚本修改这个环境变量，在脚本退出后我们再次打印这个环境变量；
<blockquote>
<p>脚本文件名为：<code>chg_envvar.sh</code>，脚本的代码如下：</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Print environment variable - ENV_VAR_1&#34;</span>
</span></span><span class="line"><span class="cl">printenv ENV_VAR_1
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Change ENV_VAR_1 to &#39;second_value&#39;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">ENV_VAR_1</span><span class="o">=</span><span class="s2">&#34;second value&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Again, print environment variable - ENV_VAR_1&#34;</span>
</span></span><span class="line"><span class="cl">printenv ENV_VAR_1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">exit</span> <span class="m">0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>下面我们完成这个测试</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">whowin@ubuntu:~$ chmod +x chg_envvar.sh
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ <span class="nb">export</span> <span class="nv">ENV_VAR_1</span><span class="o">=</span><span class="s2">&#34;first value&#34;</span>
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ printenv ENV_VAR_1
</span></span><span class="line"><span class="cl">first value
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ ./chg_envvar.sh
</span></span><span class="line"><span class="cl">Print environment variable - ENV_VAR_1
</span></span><span class="line"><span class="cl">first value
</span></span><span class="line"><span class="cl">Change ENV_VAR_1 to <span class="s1">&#39;second_value&#39;</span>
</span></span><span class="line"><span class="cl">Again, print environment variable - ENV_VAR_1
</span></span><span class="line"><span class="cl">second value
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ printenv ENV_VAR_1
</span></span><span class="line"><span class="cl">first value
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$
</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>我们看到，在脚本内部执行 <code>printenv ENV_VAR_1</code> 时，打印出来的结果已经是 <code>second value</code>，说明我们已经修改成功了这个环境变量的值，但当脚本退出，我们再次打印这个变量时，其值仍然是 <code>first value</code>，并没有改变，这说明我们在子进程中对环境的修改并不能影响到父进程。</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<h2 id="5-在当前环境下运行程序">5. 在当前环境下运行程序</h2>
<ul>
<li>
<p>我们在前面一再强调，<code>shell</code> 在执行一个程序的时候会先 <code>fork</code> 一个子进程，然后在子进程中执行程序，这实际上是 <code>shell</code> 为执行一个程序新建立了一个环境，然后在这个环境中执行程序，当然这个新环境继承了父进程的环境；</p>
</li>
<li>
<p>其实，<code>shell</code> 也可以不 <code>fork</code> 一个子进程，而是直接在当前进程下执行你的程序，<code>shell</code> 下有一个内建命令 <code>source</code> 就是为此而设计的，我们先来看看这个命令的手册：</p>
<p><img src="https://whowin.gitee.io/images/100001/source_help.png" alt="source的help手册"></p>
<center><b>图10：source命令的help手册</b></center>
</li>
</ul>
<hr>
<ul>
<li>
<p>说明已经很清楚了，要说明的是 <code>source</code> 命令只能执行脚本文件；</p>
</li>
<li>
<p>我们提出的问题是，既然 <code>source</code> 命令是在当前 <code>shell</code> 下执行程序，那是不是意味着上面那个改变环境变量的脚本文件可以改变当前 <code>shell</code> 下的环境变量了呢？我们执行一下试试；</p>
</li>
<li>
<p>我们在前面执行脚本时使用的命令是：<code>./chg_envvar.sh</code>，我们已经解释过 <code>&quot;./&quot;</code> 的含义以及为什么要有 <code>&quot;./&quot;</code>，这次我们执行这个脚本准备用 <code>. ./chg_envvar.sh</code> 来执行，只是在原来命令的前面多了 <code>&quot;. &quot;</code>，点后面有个空格，其实这个 <code>&quot;.&quot;</code> 就等同于 <code>source</code>，所以这个命令就相当于 <code>source ./chg_envvar.sh</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">whowin@ubuntu:~$ . ./chg_envvar.sh
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>当我们用这种方法执行这个脚本的时候，我们发现意外出现了，整个 <code>shell</code> 都退出了，这是为什么呢？</p>
<blockquote>
<p>这是因为在我们的脚本的最后一行有一个 <strong>exit 0</strong> 语句，正常情况下，如果我们不使用 <code>source</code> 去运行时，<strong>exit</strong> 会退出 <code>shell</code> 为这个脚本建立的子进程，所以一点问题都没有，但是当用 <code>source</code> 去运行这个脚本时，没有建立子进程，那么退出的就是当前 <code>shell</code> 进程，所以你的 <code>shell</code> 就没有了，因为被你运行的脚本退出了；但是如果我们不使用 <strong>exit</strong> 而使用 <strong>return</strong> 退出确实是可以解决在使用 <code>source</code> 命令运行的问题，但是不使用 <code>source</code> 运行就要出问题了，大家自己可以试一下；</p>
</blockquote>
<blockquote>
<p>那么是不是可以不写 <strong>exit</strong> 和 <strong>return</strong> 呢？当然可以，但是这不是写 <code>shell</code> 脚本的好习惯，因为执行完你的脚本后，可能还要执行下一个脚本，而下一个脚本可能要判断你的这个脚本的返回值，所以在写脚本时返回一个有意义的值是非常良好的习惯；</p>
</blockquote>
<blockquote>
<p>其实我们修改一下这个脚本就可以解决这个问题，这里仅提供源码，解释超出了本文涉及的内容：</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">whowin@ubuntu:~$ cat chg_envvar.sh 
</span></span><span class="line"><span class="cl"><span class="c1">#!/bin/bash</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Print environment variable - ENV_VAR_1&#34;</span>
</span></span><span class="line"><span class="cl">printenv ENV_VAR_1
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Change ENV_VAR_1 to &#39;second_value&#39;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">ENV_VAR_1</span><span class="o">=</span><span class="s2">&#34;second value&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Again, print environment variable - ENV_VAR_1&#34;</span>
</span></span><span class="line"><span class="cl">printenv ENV_VAR_1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="nv">$0</span> !<span class="o">=</span> <span class="s2">&#34;</span><span class="nv">$BASH_SOURCE</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="nb">exit</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>用这种方法，也可以让某些必须用 <code>source</code> 运行的程序如果没有在 <code>source</code> 下运行，可以给出提示并停止运行；</p>
</li>
<li>
<p>现在回到正题，这个脚本能不能改变当前 <code>shell</code> 下的环境变量呢？答案是肯定的。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">whowin@ubuntu:~$ export ENV_VAR_1=&#34;first value&#34;
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ printenv ENV_VAR_1
</span></span><span class="line"><span class="cl">first value
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ source ./chg_envvar.sh 
</span></span><span class="line"><span class="cl">Print environment variable - ENV_VAR_1
</span></span><span class="line"><span class="cl">first value
</span></span><span class="line"><span class="cl">Change ENV_VAR_1 to &#39;second_value&#39;
</span></span><span class="line"><span class="cl">Again, print environment variable - ENV_VAR_1
</span></span><span class="line"><span class="cl">second value
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ printenv ENV_VAR_1
</span></span><span class="line"><span class="cl">second value
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>很显然，脚本 <code>chg_envvar.sh</code> 运行完毕后，我们发现，环境变量 <strong>ENV_VAR_1</strong> 已经发生了改变；</p>
</li>
<li>
<p>实际上这种方法是一种常用的方法，常被用于改变当前环境；</p>
<blockquote>
<p>在嵌入式开发中，不同的开发板使用的 <code>CPU</code> 可能不同，这样在交叉编译时的工具链也不同，不同的开发板即便是相同的CPU也可能使用不同的工具链进行编译，比如即便是相同的CPU可能有些需要用软浮点的编译器，有些使用硬浮点的编译器，这时我们可以用上面的方法为每一个交叉编译的工具链写一个脚本，脚本中为某个指定的工具链所需的环境，然后用 <code>source</code> 去运行，下面是我的环境下的一个例子：</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">whowin@ubuntu:~$ cat a8.sh
</span></span><span class="line"><span class="cl"><span class="c1">#!/bin/bash</span>
</span></span><span class="line"><span class="cl"><span class="c1">#A8 arm-linux-gnueabi工具链</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span>/home/whowin/toolschain/4.5.1/bin:<span class="nv">$PATH</span>
</span></span><span class="line"><span class="cl">whowin@ubuntu:~$ 
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h2 id="6-结语">6. 结语</h2>
<ul>
<li>启动终端程序时启动了 <strong>bash</strong> 进程，使我们可以在 <strong>shell</strong> 下输入命令；</li>
<li>环境变量也是 <code>shell</code> 变量，但又与 <code>shell</code> 变量略有不同；</li>
<li>环境变量与普通 <code>shell</code> 变量的主要区别是环境变量会传递给新建的子进程；</li>
<li>环境变量和普通 <code>shell</code> 变量之间可以使用 <code>export</code> 或 <code>declare</code> 进行转换；</li>
<li><code>shell</code> 可以在当前进程下运行脚本程序(不创建子进程)，这种运行方式常被用于改变当前运行环境下的环境变量。</li>
</ul>
<hr>
<p><strong>欢迎访问我的博客：https://whowin.cn</strong></p>
<p><strong>email: <a href="mailto:hengch@163.com">hengch@163.com</a></strong></p>
<p><img src="https://whowin.gitee.io/images/qrcode/sponsor-qrcode.png" alt="donation"></p>
<!-- CSDN
[img_01]:https://img-blog.csdnimg.cn/img_convert/e7a727e73f0834c251a4e18f8834eb96.png
[img_02]:https://img-blog.csdnimg.cn/img_convert/0c652bec4e82d827e93a15be41601465.png
[img_03]:https://img-blog.csdnimg.cn/img_convert/f97de9b9146cd504c205f29aea6753db.png
[img_04]:https://img-blog.csdnimg.cn/img_convert/07024a1b07f4fb8fdb363ce8a1cfb8e5.png
[img_05]:https://img-blog.csdnimg.cn/img_convert/f9e3f07c0ab20eb7302b800f92280d1b.png
[img_06]:https://img-blog.csdnimg.cn/img_convert/9a11ac9ac87b9fc222ba54b1008022bb.png
[img_07]:https://img-blog.csdnimg.cn/img_convert/86851d1f588a77060fb369ad67eaee97.png
[img_08]:https://img-blog.csdnimg.cn/img_convert/5543f2dd128f2a158c60bdfb93ab7ef6.png
[img_09]:https://img-blog.csdnimg.cn/img_convert/f26b84020c65ff4f2dc2ad8257b9394f.png
[img_10]:https://img-blog.csdnimg.cn/img_convert/8d2f722f755a57c6c1cd1fbd7b5a9b82.png
-->
    </div>

    <div class="post-copyright">
  <p class="copyright-item">
    <span class="item-title">文章作者</span>
    <span class="item-content">whowin</span>
  </p>
  <p class="copyright-item">
    <span class="item-title">上次更新</span>
    <span class="item-content">
        2022-04-10
        
    </span>
  </p>
  
  
</div>
<footer class="post-footer">
      <div class="post-tags">
          <a href="/tags/shell/">shell</a>
          <a href="/tags/bash/">bash</a>
          <a href="/tags/source/">source</a>
          <a href="/tags/printenv/">printenv</a>
          <a href="/tags/%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F/">环境变量</a>
          <a href="/tags/declare/">declare</a>
          <a href="/tags/export/">export</a>
          </div>
      <nav class="post-nav">
        <a class="prev" href="/post/blog/linux/0004-setup-ps1/">
            <i class="iconfont icon-left"></i>
            <span class="prev-text nav-default">bash下变量PS1的完整理解</span>
            <span class="prev-text nav-mobile">上一篇</span>
          </a>
        <a class="next" href="/post/blog/linux/0003-ansi-escape-code/">
            <span class="next-text nav-default">ANSI的ESC转义序列</span>
            <span class="next-text nav-mobile">下一篇</span>
            <i class="iconfont icon-right"></i>
          </a>
      </nav>
    </footer>
  </article>
        </div>
        

  <span id="/post/blog/linux/0001-environment-variables-and-shell-variables/" class="leancloud_visitors" data-flag-title="bash 的环境变量和 shell 变量">
		<span class="post-meta-item-text">文章阅读量 </span>
		<span class="leancloud-visitors-count">0</span>
		<p></p>
	  </span>
  <div id="vcomments"></div>
  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
  <script type="text/javascript">
    new Valine({
        el: '#vcomments' ,
        appId: 'OFCGzCfJRUglzOdzrqMGkbTR-gzGzoHsz',
        appKey: 'v7P29kPAEbsmaavaYPNhGhnF',
        notify:  false ,
        verify:  false ,
        avatar:'mm',
        placeholder: '说点什么吧...',
        visitor:  true 
    });
  </script>

  

      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="social-links">
      <a href="mailto:hengch@163.com" class="iconfont icon-email" title="email"></a>
  <a href="https://whowin.gitee.io/index.xml" type="application/rss+xml" class="iconfont icon-rss" title="rss"></a>
</div>
<div class="copyright">
  <span class="power-by">
    由 <a class="hexo-link" href="https://gohugo.io">Hugo</a> 强力驱动
  </span>
  <span class="division">|</span>
  <span class="theme-info">
    主题 - 
    <a class="theme-link" href="https://github.com/olOwOlo/hugo-theme-even">Even</a>
  </span>

  <div class="busuanzi-footer">
    <span id="busuanzi_container_site_pv"> 本站总访问量 <span id="busuanzi_value_site_pv"><img src="/img/spinner.svg" alt="spinner.svg"/></span> 次 </span>
      <span class="division">|</span>
    <span id="busuanzi_container_site_uv"> 本站总访客数 <span id="busuanzi_value_site_uv"><img src="/img/spinner.svg" alt="spinner.svg"/></span> 人 </span>
  </div>

  <span class="copyright-year">
    &copy; 
    2022 - 
    2024<span class="heart"><i class="iconfont icon-heart"></i></span><span>whowin</span>
  </span>
</div>

    </footer>

    <div class="back-to-top" id="back-to-top">
      <i class="iconfont icon-up"></i>
    </div>
  </div>
  
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/slideout@1.0.1/dist/slideout.min.js" integrity="sha256-t+zJ/g8/KXIJMjSVQdnibt4dlaDxc9zXr/9oNPeWqdg=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.1.20/dist/jquery.fancybox.min.js" integrity="sha256-XVLffZaxoWfGUEbdzuLi7pwaUJv1cecsQJQqGLe7axY=" crossorigin="anonymous"></script>



<script type="text/javascript" src="/js/main.min.64437849d125a2d603b3e71d6de5225d641a32d17168a58106e0b61852079683.js"></script>
  <script type="text/javascript">
    window.MathJax = {
      tex: {
        inlineMath: [['$','$'], ['\\(','\\)']],
        }
    };
  </script>
  <script async src="https://cdn.jsdelivr.net/npm/mathjax@3.0.5/es5/tex-mml-chtml.js" integrity="sha256-HGLuEfFcsUJGhvB8cQ8nr0gai9EucOOaIxFw7qxmd+w=" crossorigin="anonymous"></script>








</body>
</html>
